a694: 吞食天地二
內容
好餓歐歐歐歐
有 n * n 個食物在你面前排成一個方陣
每個食物有它的飽足度
你想知道把其中一塊通通吃掉會獲得多少飽足度
輸入
多組測資以 EOF 結束
每組測資開始有兩個正整數 n,m (n<=500, m<=100000)
接下來 n 行有 n 個不超過 100 的正整數依序代表每個食物的飽足度
接下來 m 行每行有四個數字 x1,y1,x2,y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n)
代表你想要吃掉食物的範圍
3 3
1 2 3
4 5 6
7 8 9
1 1 3 3
1 1 1 3
1 1 3 1
輸出
對每組測資輸出 m 行,代表總飽足度
45
6
12
解題思路
吞食天地 的加強版,從一維變成二維,但解題邏輯一樣是建立總飽足度陣列之後用數學去取得目標區間。
建立總飽足度的二維陣列
總飽讀度計算流程(sum 為總飽足度矩陣):
. . . .
. . . .
. . s . 如果要計算 s 點
. . . .
1 1 . .
1 1 . .
1 1 0 . + 先加上 sum[s.X - 1][s.Y]
. . . . (數字為該區域飽足度被計算到的次數)
2 2 1 .
2 2 1 .
1 1 0 . 再加上 sum[s.X][s.Y - 1]
. . . . (這時候由於 2 的區域飽足感被重複加了兩次,所以待會要減掉)
1 1 1 .
1 1 1 .
1 1 0 . 減到 sum[s.X -1][s.Y - 1]
. . . .
1 1 1 .
1 1 1 .
1 1 1 . 最後加上 s點本身的飽足感即可。
. . . .
觀察上面流程得到以下公式
sum[s.X][s.y] = sum[s.X - 1][s.y] + sum[s.X][s.y - 1] - sum[s.X - 1][s.y - 1] + s 點的飽足感
取得 s 點到 e 點的區域飽足度
計算流程範例 :
. . . . .
. s 0 0 .
. 0 0 0 . 如果要計算 s 到 e 區域的的飽足度
. 0 0 e . (也就是 s + e + 0 區域)
. . . . .
1 1 1 1 .
1 1 1 1 .
1 1 1 1 . 先加上 sum[e.X][e.Y] 點的飽足度
1 1 1 1 .
. . . . .
0 1 1 1 .
0 1 1 1 .
0 1 1 1 . 減掉 sum[e.X][s.Y - 1] 點的飽足度
0 1 1 1 .
. . . . .
-1 0 0 0 .
0 1 1 1 .
0 1 1 1 . 減掉 sum[s.X - 1][e.Y] 點的飽足度
0 1 1 1 .
. . . . .
0 0 0 0 .
0 1 1 1 .
0 1 1 1 . 加上 sum[s.X - 1][s.Y - 1] 點的飽足度,就會得到目標區域
0 1 1 1 .
. . . . .
觀察上面流程得到以下公式
s 到 e 點的總飽和度 = sum[e.X][e.y] - sum[e.X][s.y - 1] - sum[s.X - 1][e.y] + sum[s.X - 1][s.y - 1]
計算後輸出答案即可。
完整程式碼
AC (68ms, 728KB)
|